package com.hgz.ssmdemo.common.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.Properties;

/**
 * mybatis配置类
 * 1、获取所有的mapper接口
 * 2、配置数据源
 * 3、配置mybatis的工厂bean
 * 4、开启事务管理器
 * @author 小志
 * @date 2025/6/25 - 14:32
 */
@Configuration
// 扫描当前的mapper包
@MapperScan("com.hgz.ssmdemo.mapper")
//启用事务注解管理器
@EnableTransactionManagement
public class MybatisConfig {


    /**
     * 配置druid连接池
     * 1、配置注册销毁方法（init,close）
     * 2、获取druid配置文件获取数据源
     * @return 数据源
     * @throws Exception 抛出异常
     */
    @Bean(initMethod = "init",destroyMethod = "close")
    public DruidDataSource  dataSource()  throws Exception{
        // 读取druid配置
        Properties properties = new Properties();
        // 获取到当前的配置文件并加载
        InputStream druid = MybatisConfig.class.getClassLoader().getResourceAsStream("druid.properties");
        properties.load(druid);
        // 使用 DruidDataSourceFactory的静态方法createDataSource获取到DruidDataSource
        return (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
    }

    /**
     * 配置Mybatis的工厂Bean
     * 1、配置数据源
     * 2、配置实体包
     * 3、配置xml文件映射
     * 4、注册分页插件
     * 5、启动sql日志
     * @return 一个配置好的SqlSessionFactoryBean
     * @throws Exception 配置报错
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
        // 创建 SqlSessionFactoryBean 对象
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        // 注入数据源
        factoryBean.setDataSource(dataSource());
        // 设置实体别名,让 MyBatis 扫描该包中的类，在 XML 中可以直接写 User 而不是全限定名
        factoryBean.setTypeAliasesPackage("com.hgz.ssmdemo.entity");
        // 设置mapper.xml的文件映射路径
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factoryBean.setMapperLocations(resolver.getResources("classpath:/mappers/*.xml"));
        // 设置分页插件
        PageInterceptor pageInterceptor = new PageInterceptor();
        // 设置分页属性
        Properties properties = new Properties();
        properties.load(MybatisConfig.class.getClassLoader().getResourceAsStream("pagerHelper.properties"));
        pageInterceptor.setProperties(properties);
        // 将分页拦截器添加到插件中
        factoryBean.setPlugins(pageInterceptor);
        // 启用sql日志
        org.apache.ibatis.session.Configuration conf = new org.apache.ibatis.session.Configuration();
        conf.setLogImpl(StdOutImpl.class);
        factoryBean.setConfiguration(conf);
        return factoryBean;
    }

    /**
     * 装配事务管理器
     * 装配后会识别 @Transactional 注解
     */
    @Bean
    public PlatformTransactionManager txManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
